package com.hh.shiro;

import java.util.Set;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;

/**
 * jedis manager
 *
 */
public class JedisManager {

    private JedisPool jedisPool;

    public Jedis getJedis() {
        Jedis jedis = null;
        try {
            jedis = getJedisPool().getResource();
        } catch (Exception e) {
            throw new JedisConnectionException(e);
        }
        return jedis;
    }

    public void returnResource(Jedis jedis, boolean isBroken) {
        if (jedis == null) {
        	return;
        }
        if (isBroken) {
        	getJedisPool().returnBrokenResource(jedis);
        } else {
        	getJedisPool().returnResource(jedis);
        }
    }

    public byte[] getValueByKey(int dbIndex, byte[] key) {
        Jedis jedis = null;
        byte[] result = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            result = jedis.get(key);
        } catch (Exception e) {
            isBroken = true;
        } finally {
            returnResource(jedis, isBroken);
        }
        return result;
    }

    public void deleteByKey(int dbIndex, byte[] key) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            jedis.del(key);
        } catch (Exception e) {
            isBroken = true;
        } finally {
            returnResource(jedis, isBroken);
        }
    }
    
    /**
	 * del
	 * 
	 * @param regex
	 * @return
	 */
	public Long del(int dbIndex, byte[]... keys) {
        Jedis jedis = null;
        Long result = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            result = jedis.del(keys);
        } catch (Exception e) {
            isBroken = true;
        } finally {
            returnResource(jedis, isBroken);
        }
        return result;
    }

    public void saveValueByKey(int dbIndex, byte[] key, byte[] value, int expireTime) {
        Jedis jedis = null;
        boolean isBroken = false;
        try {
            jedis = getJedis();
            jedis.select(dbIndex);
            jedis.set(key, value);
            if (expireTime > 0) {
            	jedis.expire(key, expireTime);
            }
        } catch (Exception e) {
            isBroken = true;
        } finally {
            returnResource(jedis, isBroken);
        }
    }
    
    /**
	 * keys
	 * 
	 * @param regex
	 * @return
	 */
	public Set<byte[]> keys(int dbIndex, String pattern) {
		Jedis jedis = null;
        boolean isBroken = false;
		Set<byte[]> keys = null;
		try {
			jedis = getJedis();
            jedis.select(dbIndex);
			keys = jedis.keys(pattern.getBytes());
		} finally {
			returnResource(jedis, isBroken);
		}
		return keys;
	}
	
	/**
	 * exists
	 * 
	 * @param regex
	 * @return
	 */
	public Boolean exists(int dbIndex, String pattern) {
		Jedis jedis = null;
        boolean isBroken = false;
        Boolean exists = null;
		try {
			jedis = getJedis();
            jedis.select(dbIndex);
            exists = jedis.exists(pattern.getBytes());
		} finally {
			returnResource(jedis, isBroken);
		}
		return exists;
	}
	
	/**
	 * flush
	 */
	public void flushDB() {
		Jedis jedis = jedisPool.getResource();
		try {
			jedis.flushDB();
		} finally {
			jedisPool.returnResource(jedis);
		}
	}
	
	/**
	 * size
	 */
	public Long dbSize() {
		Long dbSize = 0L;
		Jedis jedis = jedisPool.getResource();
		try {
			dbSize = jedis.dbSize();
		} finally {
			jedisPool.returnResource(jedis);
		}
		return dbSize;
	}
	
	/**
	 * keys
	 * 
	 * @param regex
	 * @return
	 */
	public Set<byte[]> keys(String pattern) {
		Set<byte[]> keys = null;
		Jedis jedis = jedisPool.getResource();
		try {
			keys = jedis.keys(pattern.getBytes());
		} finally {
			jedisPool.returnResource(jedis);
		}
		return keys;
	}
	

    public JedisPool getJedisPool() {
        return jedisPool;
    }

    public void setJedisPool(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

}
